package main

import (
	"common"
	"common/middleware"
	"config"
	"context"
	"epai/internal/handler"
	"errors"
	"fmt"
	"github.com/gin-gonic/gin"
	"log"
	"net/http"
	"os"
	"os/signal"
	"pkg/cache/redis"
	"pkg/db_mysql"
	"pkg/jwt"
	"pkg/third/wechat"
	"syscall"
	"time"
	"ucenter"
)

const ServiceName = "epai"

func main() {
	serverInfo := config.GetServerInfo(ServiceName)
	r := gin.Default()
	srv := &http.Server{
		Addr:    serverInfo.Addr,
		Handler: r,
	}

	configFile := os.Getenv(serverInfo.ConfigFileName)
	c := config.GetConfig(configFile)
	if c.AppEnv.Name == "production" {
		gin.SetMode(gin.ReleaseMode)
	} else {
		gin.SetMode(gin.DebugMode)
	}
	ctx := context.Background()

	// 设置时区为8区
	time.Local = time.FixedZone("UTC+8", 8*60*60)
	mainChannel := make(chan interface{}, 1000)
	redisClient := redis.NewRedis(c.Redis.Addr, c.Redis.DB)
	ucUser := ucenter.NewUcUser(ServiceName)
	g := &common.Global{
		AppID:     ServiceName,
		DB:        db_mysql.NewDb(c.DB.User, c.DB.Password, c.DB.Host, c.DB.Port, c.DB.DBName, gin.Mode() == gin.DebugMode, c.DB.MaxOpen, c.DB.MaxIdle),
		JwtCommon: jwt.NewClient(c.JwtCommon.SigningKey, c.JwtCommon.Issuer, c.JwtCommon.ExpiresTime),
		WeChatSdk: wechat.NewMiniProgramSdk(&ctx, c.WeChat.AppId, c.WeChat.AppSecret, redisClient, common.CK_WECHATTOKEN),
		//WeChatSdkEpai: wechat.NewWOASdk(&ctx, c.WeChatEpai.AppId, c.WeChatEpai.AppSecret, redisClient, common.CK_WECHATTOKEN_EPAI),
		Redis:       redisClient,
		Config:      c,
		MainChannel: mainChannel,
		UCenter: &ucenter.UCenter{
			User: ucUser,
		},
	}

	go ListenMainChannel(ctx, mainChannel, c, ServiceName)

	router(r, g, c)

	// 启动服务器
	log.Printf("start listen %s\n", serverInfo.Addr)
	go func() {
		defer common.RecoverHandler()
		if err := srv.ListenAndServe(); err != nil && !errors.Is(err, http.ErrServerClosed) {
			log.Fatalf("listen: %s\n", err)
		}
	}()

	// 等待中断信号（如按下Ctrl+C）来优雅地关闭服务器
	quit := make(chan os.Signal, 1)
	signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
	<-quit
	// 设置超时时间
	timeoutCtx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
	defer cancel()

	// 关闭 HTTP 服务器
	log.Println("shutting down server...")
	if err := srv.Shutdown(timeoutCtx); err != nil {
		log.Fatal("server shutdown:", err)
	}
	log.Println("server exiting")
}

func ListenMainChannel(ctx context.Context, mainChannel chan interface{}, c *config.Config, logName string) {
	for {
		select {
		case msg, ok := <-mainChannel:
			// 如果通道关闭，则退出循环
			if !ok {
				fmt.Println("Channel closed.")
				return
			}
			if data, ok := msg.(common.BusinessError); ok {
				common.WriteLog(ctx, &data, c, logName)
			}
		}
	}
}

func router(r *gin.Engine, g *common.Global, c *config.Config) {
	//基础路由组
	baseGroup := r.Group("/api", middleware.CommonContext(g, c))
	// GET请求微信开发者配置验证
	baseGroup.GET("wx_check", middleware.CommonHandlerWrapper(handler.WxCheckSignature))
	// 接收微信公众号请求的消息
	baseGroup.POST("wx_check", middleware.CommonHandlerWrapper(handler.Autoresponder))
	// 创建自定义菜单
	baseGroup.POST("create_menu", middleware.CommonHandlerWrapper(handler.CreateMenu))
	//判活
	baseGroup.GET("ping", middleware.CommonHandlerWrapper(handler.Ping))
	// 发验证码
	baseGroup.POST("send_sms_code", middleware.CommonHandlerWrapper(handler.SendSmsCode))
	baseGroup.POST("login", middleware.CommonHandlerWrapper(handler.Login))

	// 获取所有商品分类
	baseGroup.GET("goods_category_list", middleware.CommonHandlerWrapper(handler.GoodsCategoryList))
	// 增加商品表格
	baseGroup.POST("goods_add", middleware.CommonHandlerWrapper(handler.GoodsAdd))
	// 删除单个商品
	baseGroup.POST("goods_del", middleware.CommonHandlerWrapper(handler.GoodsDel))
	// 获取单个商品
	baseGroup.GET("goods_info", middleware.CommonHandlerWrapper(handler.GoodsInfo))
	// 获取商品列表
	baseGroup.GET("goods_list", middleware.CommonHandlerWrapper(handler.GoodsList))
	// 获取商品总数
	baseGroup.GET("goods_sum", middleware.CommonHandlerWrapper(handler.GoodsSum))
	// 增加商店表格
	baseGroup.POST("shop_add", middleware.CommonHandlerWrapper(handler.AddShops))
	// 删除单个商店
	baseGroup.POST("shop_del", middleware.CommonHandlerWrapper(handler.DelShop))
	// 获取单个商店
	baseGroup.GET("shop_info", middleware.CommonHandlerWrapper(handler.GetShop))
	// 获取商店列表
	baseGroup.GET("shop_list", middleware.CommonHandlerWrapper(handler.ShopList))
	// 获取商店总数
	baseGroup.GET("shop_sum", middleware.CommonHandlerWrapper(handler.ShopSum))
	// app_env_set
	baseGroup.GET("book", middleware.CommonHandlerWrapper(handler.Book))

	// 通过经纬度获取地址名字
	baseGroup.GET("address_name", middleware.CommonHandlerWrapper(handler.GetAddressName))

	// 获取档期信息
	baseGroup.GET("schedule_list", middleware.CommonHandlerWrapper(handler.ScheduleList))
	//需要验签的路由组
	verifyGroup := baseGroup.Group("/biz")
	// 加入验签中间件
	verifyGroup.Use(middleware.CommonJwt(g.JwtCommon))
	baseGroup.POST("upload_image", middleware.CommonHandlerWrapper(handler.UploadImage))
	verifyGroup.POST("book_slots", middleware.CommonHandlerWrapper(handler.BookSlots))

	//zhe
	baseGroup.GET("random_qr", middleware.CommonHandlerWrapper(handler.RandomQr))

	//verifyGroup.POST("update_user", middleware.CommonHandlerWrapper(handler.UpdateUser))
	//
	////login
	//baseGroup.POST("login", middleware.CommonHandlerWrapper(handler.Login))
	////当前用户信息
	//verifyGroup.GET("current_user", middleware.CommonHandlerWrapper(handler.CurrentUser))
	////提醒的核心业务逻辑
	//verifyGroup.POST("remind", middleware.CommonHandlerWrapper(handler.Remind))
	////事件列表
	//verifyGroup.GET("remind_list", middleware.CommonHandlerWrapper(handler.RemindList))
	////事件删除
	//verifyGroup.POST("remind_del", middleware.CommonHandlerWrapper(handler.RemindDel))
}
